﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TakaGUI;
using TakaGUI.Data;
using EvoSim.Simulation;
using Microsoft.Xna.Framework;
using TakaGUI.Services;

namespace EvoSim.DrawBoxes
{
	public class WorldBox : DrawBox
	{
		public static string DefaultCategory = "Simulation/WorldBox";
		public ISprite Creature;
		public ISprite Food;

		public MonoFont Font;

		public Camera ViewCamera;
		public World World;

		public bool ShowEnergyLevels = true;

		Creature infoDrawCreature;

		public virtual void Initialize()
		{
			Initialize(DefaultSkinFile);
		}
		public virtual void Initialize(ISkinFile file)
		{
			Initialize(DefaultCategory, file);
		}
		public virtual void Initialize(string category, ISkinFile file)
		{
			Creature = GetTexture(file, category, "Creature");
			Food = GetTexture(file, category, "Food");

			Font = GetMonoFont(file, category, "Font");

			base.BaseInitialize();
		}

		public override void Idle(GameTime gameTime)
		{
			base.Idle(gameTime);

			if (KeyboardInput.IsClicked(Microsoft.Xna.Framework.Input.Keys.Space))
				Hidden = !Hidden;

			if (IsUnderMouse && MouseInput.IsClicked(MouseButtons.Left))
			{
				foreach (var creature in World.CreatureList)
				{
					var entityRect = new Rectangle((int)creature.PosX + RealX - ViewCamera.LookX - creature.Radius / 2,
													(int)creature.PosY + RealY - ViewCamera.LookY - creature.Radius / 2,
													creature.Radius,
													creature.Radius);

					if (MouseInput.X >= entityRect.Left && MouseInput.Y >= entityRect.Top &&
						MouseInput.X <= entityRect.Right && MouseInput.Y <= entityRect.Bottom)
					{
						infoDrawCreature = creature;
					}
				}
			}

			World.Update(gameTime);
		}

		public override void Project(GameTime gameTime, int x, int y, IRender render)
		{
			render.Begin();

			int originX = ViewCamera.LookX;
			int originY = ViewCamera.LookY;

			ISprite sprite = null;

			foreach (Entity entity in World.EntityList)
			{
				Color color = entity.EntityColor;

				switch (entity.EntityName)
				{
					case "Creature":
						sprite = Creature;

						double energyQ = ((Creature)entity).Energy.Value / ((Creature)entity).Energy.Max;
						color.R = (byte)Math.Round(color.R * energyQ, 0);
						color.G = (byte)Math.Round(color.G * energyQ, 0);
						color.B = (byte)Math.Round(color.B * energyQ, 0);
						break;
					case "Food":
						sprite = Food;
						break;
				}

				Rectangle destRect = new Rectangle((int)Math.Round(entity.PosX - originX, 0),
													(int)Math.Round(entity.PosY - originY, 0),
													entity.Radius,
													entity.Radius);
				render.DrawSprite(sprite, destRect, new Vector2(entity.Radius / 2, entity.Radius / 2), color, (float)entity.Rotation);

				//if (entity.EntityName == "Creature")
				//{
				//    var creature = (Creature)entity;
				//    double rotation = (creature.Rotation - creature.EyeSpan / 2);
				//    double rotationStep = creature.EyeSpan / creature.EyeNeurons;
				//    float length = 64;

				//    for (int i = 0; i < creature.EyeNeurons + 1; i++)
				//    {
				//        float posX = (float)entity.PosX + x;
				//        float posY = (float)entity.PosY + y;
				//        float lineX = (float)Math.Cos(rotation) * length + posX;
				//        float lineY = (float)Math.Sin(rotation) * length + posY;
				//        render.DrawLine(new Vector2(posX, posY), new Vector2(lineX, lineY), Color.Red);
				//        rotation += rotationStep;
				//    }
				//}
			}

			if (infoDrawCreature != null)
			{
				Color color = Color.White;

				int tX = 10;
				int tY = 30;
				Font.DrawString("PixelsRotatedLeft: " + infoDrawCreature.PixelsRotatedLeft, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 2;
				Font.DrawString("PixelsRotatedRight: " + infoDrawCreature.PixelsRotatedRight, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 2;
				Font.DrawString("PixelsMovedForwards: " + infoDrawCreature.PixelsMovedForwards, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 2;
				Font.DrawString("PixelsMovedBackwards: " + infoDrawCreature.PixelsMovedBackwards, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 4;
				Font.DrawString("TimesHaveEaten: " + infoDrawCreature.TimesHaveEaten, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 2;
				Font.DrawString("TimesMated: " + infoDrawCreature.TimesMated, new Point(tX, tY), color, render);
				tY += Font.CharHeight + 2;
			}

			render.End();
		}

		public struct Camera
		{
			int lookX;
			int lookY;
			public int LookX
			{
				get
				{
					if (LookAt == null)
						return lookX;
					else
						return (int)LookAt.PosX;
				}
				set
				{
					lookX = value;
				}
			}
			public int LookY
			{
				get
				{
					if (LookAt == null)
						return lookY;
					else
						return (int)LookAt.PosY;
				}
				set
				{
					lookY = value;
				}
			}

			public Entity LookAt;
		}
	}
}
